#!/usr/bin/env python3
"""
访客管理路由
"""

from datetime import datetime


from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.ext.asyncio.session import AsyncSession
from sqlalchemy.future import select

from app.database.session import get_db
from app.models.visitor import Visitor
from app.schemas.visitor import VisitorCreate, VisitorListResponse, VisitorResponse, VisitorUpdate
from app.services.audit_service import audit_log

router = APIRouter()


@router.get("/", response_model=VisitorListResponse)
async def list_visitors(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    status: str | None = Query(None, description="状态过滤"),
    name: str | None = Query(None, description="姓名搜索"),
    db: AsyncSession = Depends(get_db),
):
    """
    获取访客列表

    Args:
        page: 页码
        page_size: 每页数量
        status: 状态过滤
        name: 姓名搜索
        db: 数据库会话

    Returns:
        VisitorListResponse: 访客列表响应
    """
    try:
        # 构建查询条件
        query = select(Visitor)

        if status:
            query = query.where(Visitor.status == status)
        if name:
            query = query.where(Visitor.name.ilike(f"%{name}%"))

        from typing import Any
        from sqlalchemy.sql.elements import ColumnElement
        
        # 计算分页
        where_clauses: list[ColumnElement[Any]] = []
        if query.whereclause is not None:
            where_clauses.append(query.whereclause)
        
        total_query = select(Visitor)
        if where_clauses:
            total_query = total_query.where(*where_clauses)
        
        total_result = await db.execute(total_query)
        total = len(total_result.scalars().all())

        # 获取分页数据
        query = query.order_by(Visitor.created_at.desc())
        query = query.offset((page - 1) * page_size).limit(page_size)

        result = await db.execute(query)
        visitors = result.scalars().all()

        # 记录审计日志
        await audit_log(
            db=db,
            operator="system",
            operation_type="list_visitors",
            operation_target="visitors",
            operation_details={"page": page, "page_size": page_size, "total": total},
        )

        return VisitorListResponse(
            data=list(visitors), total=total, page=page, page_size=page_size, total_pages=(total + page_size - 1) // page_size
        )

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取访客列表失败: {str(e)}")


@router.post("/", response_model=VisitorResponse, status_code=status.HTTP_201_CREATED)
async def create_visitor(visitor_data: VisitorCreate, db: AsyncSession = Depends(get_db)):
    """
    创建访客信息

    Args:
        visitor_data: 访客创建数据
        db: 数据库会话

    Returns:
        VisitorResponse: 创建的访客信息
    """
    try:
        # 检查身份证号是否已存在
        existing_visitor = await db.execute(select(Visitor).where(Visitor.id_card == visitor_data.id_card))
        if existing_visitor.scalar_one_or_none():
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="身份证号已存在")

        # 创建访客记录
        visitor = Visitor()
        visitor.name = visitor_data.name
        visitor.phone = visitor_data.phone
        visitor.company = visitor_data.company
        visitor.visit_reason = visitor_data.visit_reason
        visitor.planned_visit_time = visitor_data.planned_visit_time
        visitor.status = "pending"
        visitor.created_at = datetime.now()
        visitor.updated_at = datetime.now()

        db.add(visitor)  # type: ignore[attr-defined]
        await db.commit()
        await db.refresh(visitor)

        # 记录审计日志
        await audit_log(
            db=db,
            operator="system",
            operation_type="create_visitor",
            operation_target="visitor",
            operation_details={"visitor_id": visitor.id, "name": visitor.name},
            related_visitor_id=visitor.id,
        )

        return VisitorResponse.model_validate(visitor)

    except HTTPException:
        raise
    except Exception as e:
        await db.rollback()
        raise HTTPException(status_code=500, detail=f"创建访客失败: {str(e)}")


@router.get("/{visitor_id}", response_model=VisitorResponse)
async def get_visitor(visitor_id: int, db: AsyncSession = Depends(get_db)):
    """
    获取单个访客信息

    Args:
        visitor_id: 访客ID
        db: 数据库会话

    Returns:
        VisitorResponse: 访客信息
    """
    try:
        result = await db.execute(select(Visitor).where(Visitor.id == visitor_id))
        visitor = result.scalar_one_or_none()

        if not visitor:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="访客不存在")

        # 记录审计日志
        await audit_log(
            db=db,
            operator="system",
            operation_type="get_visitor",
            operation_target="visitor",
            operation_details={"visitor_id": visitor_id},
            related_visitor_id=visitor_id,
        )

        return VisitorResponse.model_validate(visitor)

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取访客信息失败: {str(e)}")


@router.put("/{visitor_id}", response_model=VisitorResponse)
async def update_visitor(visitor_id: int, visitor_data: VisitorUpdate, db: AsyncSession = Depends(get_db)):
    """
    更新访客信息

    Args:
        visitor_id: 访客ID
        visitor_data: 访客更新数据
        db: 数据库会话

    Returns:
        VisitorResponse: 更新后的访客信息
    """
    try:
        result = await db.execute(select(Visitor).where(Visitor.id == visitor_id))
        visitor = result.scalar_one_or_none()

        if not visitor:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="访客不存在")

        # 更新字段
        update_data = visitor_data.model_dump(exclude_unset=True)
        for field, value in update_data.items():
            setattr(visitor, field, value)

        visitor.updated_at = datetime.now()

        await db.commit()
        await db.refresh(visitor)

        # 记录审计日志
        await audit_log(
            db=db,
            operator="system",
            operation_type="update_visitor",
            operation_target="visitor",
            operation_details={"visitor_id": visitor_id, "updated_fields": list(update_data.keys())},
            related_visitor_id=visitor_id,
        )

        return VisitorResponse.model_validate(visitor)

    except HTTPException:
        raise
    except Exception as e:
        await db.rollback()
        raise HTTPException(status_code=500, detail=f"更新访客信息失败: {str(e)}")


@router.delete("/{visitor_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_visitor(visitor_id: int, db: AsyncSession = Depends(get_db)):
    """
    删除访客信息

    Args:
        visitor_id: 访客ID
        db: 数据库会话
    """
    try:
        result = await db.execute(select(Visitor).where(Visitor.id == visitor_id))
        visitor = result.scalar_one_or_none()

        if not visitor:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="访客不存在")

        await db.delete(visitor)
        await db.commit()

        # 记录审计日志
        await audit_log(
            db=db,
            operator="system",
            operation_type="delete_visitor",
            operation_target="visitor",
            operation_details={"visitor_id": visitor_id, "name": visitor.name},
            related_visitor_id=visitor_id,
        )

    except HTTPException:
        raise
    except Exception as e:
        await db.rollback()
        raise HTTPException(status_code=500, detail=f"删除访客失败: {str(e)}")
